/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sintatico;

/**
 *
 * @author Gabriel Queiroz
 */

import java.util.List;
import java.util.ArrayList;
import token.Token;
import token.TokenAll;
import token.TokenType;

public class Sintatico {

    private List<Token> tokens; //recebe a lista de tokens vinda do léxico.
    private List<String> erros; //constroi uma lista de erros sintáticos.
    /**
     * Ponteiro referente a posição que está na leitura do código.
     */
    private int ponteiro;
    private Token toks; //Referência para o token atual.

    /**
     * Construtor da classe.
     */
    public Sintatico(){

        erros = new ArrayList<String>();
        this.ponteiro = 0;

    }

    /**
     * Método responsável por iniciar a análise sintática do código.
     */
    public void iniciaAnalise(List<Token> tokens){

        this.tokens = tokens;
        toks = tokens.get(ponteiro);
        if(this.comando()){
            System.out.println("Deu falso!!!!");
        }

    }

    public List<String> getErros() {
        return erros;
    }

    /**
     * incrementa o ponteiro para acessar o proximo token.
     */
    private void proximoToken(){
        if(ponteiro < this.tokens.size()-1){
            ponteiro++; //incrementa o ponteiro.
            toks = this.tokens.get(ponteiro); //passa para o próximo token da lista.
        }else{
            //se chegou no fim da lista adiciona o item EOF a mesma.
            this.toks = new Token(TokenAll.EOF, null, this.toks.getLinha(), TokenType.EOF);
        }
    }

    //###########################################################################################################
    //                                          PROGRAMA
    //###########################################################################################################

    public boolean programa(){
        if(this.blocoConstantes()){
            if(this.outrosBlocosPrograma()){
                return true;
            }
        }
        if(this.outrosBlocosPrograma()){
            return true;
        }
        return false;
    }

    public boolean outrosBlocosPrograma(){
        if(this.blocoVariaveis()){
            if(this.classes()){
                return true;
            }
        }
        if(this.classes()){
            return true;
        }
        return false;
    }
    //###########################################################################################################

    
    //###########################################################################################################
    //                                          CLASSES
    //###########################################################################################################

    public boolean classes(){
        if(this.classe()){
            if(this.classes()){
                return true;
            }
        }
        return true;
    }

    public boolean classe(){
        if(toks.getTipo() == TokenAll.classe){
            proximoToken();
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                proximoToken();
                if(this.complementoDecClasse()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado complemento declaração de classe ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                return false;
            }
        }
        return false;
    }

    public boolean complementoDecClasse(){
        if(toks.getTipo() == TokenAll.ABRECHAVES){
            proximoToken();
            if(this.blocosClasse()){
                if(toks.getTipo() == TokenAll.FECHACHAVES){
                    proximoToken();
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                    return false;
                }
            }
        }
        if(toks.getTipo() == TokenAll.herda_de){
            proximoToken();
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                proximoToken();
                if(toks.getTipo() == TokenAll.ABRECHAVES){
                    proximoToken();
                    if(this.blocosClasse()){
                        if(toks.getTipo() == TokenAll.FECHACHAVES){
                            proximoToken();
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                            return false;
                        }
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                return false;
            }
        }
        return false;
    }

    public boolean blocosClasse(){
        if(this.blocoConstantes()){
            if(this.outrosBlocosClasse()){
                return true;
            }
        }
        if(this.outrosBlocosClasse()){
            return true;
        }
        return true;
    }

    public boolean outrosBlocosClasse(){
        if(this.blocoVariaveis()){
            if(this.blocoMetodos()){
                return true;
            }
        }
        if(this.blocoMetodos()){
            return true;
        }
        return false;
    }
    //###########################################################################################################



    //###########################################################################################################
    //                                          BLOCOS CONSTANTES
    //###########################################################################################################

    /**
     * Verifica se o bloco de constantes está bem formado.
     */
    public boolean blocoConstantes(){
        System.out.println("entrou em constantes");

        if(toks.getTipo() == TokenAll.constantes){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABRECHAVES){
                proximoToken();
                if(this.declaracaoConstantes()){
                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                        proximoToken();
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                        return false;
                    }
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                return false;
            }
        }
       return false;
    }//fim do método constantes

    /**
     * Verifica se as declarações de constantes estão bem formadas
     */
    public boolean declaracaoConstantes(){
        System.out.println("Entrou em declaraçãoConstante.");

        if(this.decConstantesMesmoTipo()){
            if(this.declaracaoConstantes()){
                return true;
            }
        }
        return true;
    }//fim do método declaracaoConstantes

    public boolean decConstantesMesmoTipo(){
        if(this.tipoVariavel()){
            if(this.listaDecConstantes()){
                if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                    proximoToken();
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado lista de declaração constantes ");
                return false;
            }
        }
        return false;
    }

    public boolean listaDecConstantes(){
        if(this.atribuicao()){
            if(this.loopListaDecConstantes()){
                return true;
            }
        }
        return false;
    }

    public boolean loopListaDecConstantes(){
        if(toks.getTipo() == TokenAll.VIRGULA){
            if(this.listaDecConstantes()){
                return true;
            }
        }
        return true;
    }

    //###########################################################################################################

    
    //###########################################################################################################
    //                                          BLOCOS VARIÁVEIS
    //###########################################################################################################

    public boolean blocoVariaveis(){
        if(toks.getTipo() == TokenAll.variaveis){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABRECHAVES){
                proximoToken();
                if(this.declaracaoVariaveis()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                        return false;
                    }
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                return false;
            }
        }
        return false;
    }

    public boolean declaracaoVariaveis(){
        if(this.decVariaveisMesmoTipo()){
            if(this.declaracaoVariaveis()){
                return true;
            }
        }
        return true;
    }

    public boolean decVariaveisMesmoTipo(){
        if(this.tipoVariavel()){
            if(this.listaDecVariaveis()){
                if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                    proximoToken();
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado declaração de variáveis ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                proximoToken();
                if(this.complementoVariavelInstObjeto()){
                    if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                        proximoToken();
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                        return false;
                    }
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                return false;
            }
        }
        return false;
    }

    public boolean listaDecVariaveis(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.complementoDecVariaveis()){
                return true;
            }
        }
        return false;
    }

    public boolean complementoDecVariaveis(){
        if(this.proxTrechoListaDecVariaveis()){
            return true;
        }
        if(toks.getTipo() == TokenAll.ATRIBUICAO){
            proximoToken();
            if(this.segundoMembroAtribuicao()){
                if(this.proxTrechoListaDecVariaveis()){
                    return true;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado segundo membro da atribuição ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.ABRECHOCHETES){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(toks.getTipo() == TokenAll.FECHACOCHETES){
                    proximoToken();
                    if(this.proxTrechoListaDecVariaveis()){
                        return true;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"]\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética ");
                return false;
            }
        }
        return true;
    }

    public boolean proxTrechoListaDecVariaveis(){
        if(toks.getTipo() == TokenAll.VIRGULA){
            proximoToken();
            if(this.listaDecVariaveis()){
                return true;
            }
        }
        return true;
    }

    //###########################################################################################################

    /**
     * Verifica se é um tipo nativo válido
     * @return
     * Retorna verdadeiro se é um tipo válido e falso caso contrário.
     */
    public boolean tipoVariavel(){

        if((toks.getTipo() == TokenAll.inteiro) || (toks.getTipo() == TokenAll.cadeia) ||
                (toks.getTipo() == TokenAll.caractere) || (toks.getTipo() == TokenAll.real) ||
                (toks.getTipo() == TokenAll.logico)){
            return true;
        }
        return false;
    }

    //###########################################################################################################
    //                                           ATRIBUIÇÃO
    //###########################################################################################################

    public boolean atribuicao(){
        System.out.println("entrou em atribuição!");
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            System.out.println("achou identificador - atribuição: " + ponteiro);
            if(this.complementoIdAtrib()){
                System.out.println("achou complemento id atribuição - atribuição: " + ponteiro);
                return true;
            }
        }
        if(this.incrementoDecremento()){
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                proximoToken();
                System.out.println("achou incremento/decremento - atribuição: " + ponteiro);
                return true;
            }
        }
        return false;
    }//fim do método atribuicao

    public boolean complementoIdAtrib(){
        System.out.println("achou complementoIdAtribuição: " + ponteiro);
        if(this.complementoReferenciaVarAtrib()){
            System.out.println("achou complementoReferenciaVar - complementoId: " + ponteiro);
            return true;
        }
        if(this.incrementoDecremento()){
            System.out.println("achou incremento/decremento - complementoId: " + ponteiro);
            return true;
        }
        return false;
    }

    /*public boolean complementoReferenciaVarAtrib(){
        System.out.println("entrou complementoReferenciaVarAtrib: " + ponteiro);
        if(X()){
            System.out.println("achou em X complementoReferenciaVarAtrib: " + ponteiro);
            if(toks.getTipo() == TokenAll.ATRIBUICAO){
                proximoToken();
                if(this.segundoMembroAtribuicao()){
                    return true;
                }
            }
        }
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
        }
        return false;
    }
     *
     */

    public boolean complementoReferenciaVarAtrib(){
        if(this.loopAcessoAtribObjeto()){
            if(toks.getTipo() == TokenAll.ATRIBUICAO){
                proximoToken();
                if(this.segundoMembroAtribuicao()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado segundo membro da atribuição ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"=\" ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.ABRECHOCHETES){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(toks.getTipo() == TokenAll.FECHACOCHETES){
                    proximoToken();
                    if(toks.getTipo() == TokenAll.ATRIBUICAO){
                        proximoToken();
                        if(this.segundoMembroAtribuicao()){
                            return true;
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado segundo membro da atribuição ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"=\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"]\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.ATRIBUICAO){
            proximoToken();
            if(this.segundoMembroAtribuicao()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado segundo membro da atribuição ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            return true;
        }
        return false;
    }

    public boolean X(){
        if(this.loopAcessoAtribObjeto()){
            return true;
        }
        if(toks.getTipo() == TokenAll.ABRECHOCHETES){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(toks.getTipo() == TokenAll.FECHACOCHETES){
                    proximoToken();
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }
        return true;
    }

    public boolean complementoReferenciaVariavel(){
        if(this.loopAcessoAtribObjeto()){
            return true;
        }
        if(toks.getTipo() == TokenAll.ABRECHOCHETES){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(toks.getTipo() == TokenAll.FECHACOCHETES){
                    proximoToken();
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"]\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmetica ");
                return false;
            }
        }
        return true;
    }

    public boolean segundoMembroAtribuicao(){
       if(this.expressao()){
           return true;
       }
       if(this.incrementoDecremento()){
           if(toks.getTipo() == TokenAll.IDENTIFICADOR){
               proximoToken();
               return true;
           }else{
               erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
               return false;
           }
       }
       if(toks.getTipo() == TokenAll.CADEIA_CONSTANTE){
           proximoToken();
           return true;
       }
       if(toks.getTipo() == TokenAll.CHAR){
           return true;
       }
       return false;
    }

    public boolean complementoVariavelAtrib(){
        if(this.complementoFatorVariavel()){
            if(this.proxTrecMultiplicacao()){
                if(this.proxTrecSoma()){
                    return true;
                }
            }
        }
        if(this.incrementoDecremento()){
            return true;
        }
        return false;
    }

    public boolean complementoExpAritParentAtrib(){
        if(this.operadorAritmetico()){
            if(this.expressaoAritmetica()){
                return true;
            }
        }
        return true;
    }

    public boolean operadorAritmetico(){
        if((toks.getTipo() == TokenAll.SOMA) || (toks.getTipo() == TokenAll.SUBTRACAO)){
            proximoToken();
            return true;
        }
        if((toks.getTipo() == TokenAll.MULTIPLICACAO) || (toks.getTipo() == TokenAll.DIVISAO)){
            proximoToken();
            return true;
        }
        return false;
    }

    //###########################################################################################################

    /**
     * Fatora todos os métodos que iniciam com IDENTIFICADOR
     */
    @Deprecated
    public int iniciaId(){

        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(toks.getTipo() == TokenAll.ATRIBUICAO){
                atribuicao();
                return 1;
            }else
                if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                    //objeto
                    return 2;
                }
             else
                if(toks.getTipo() == TokenAll.ABREPARENTESES){
                    //chamada de método
                    return 3;
                }
             else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Símbolo inesperado! ");
             }
        }else{
            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador! ");
        }
        return 0;
    }

    public boolean chamadaObjeto(){
        return false;
    }


    //###########################################################################################################
    //                                           EXPRESSÕES
    //###########################################################################################################

    public boolean expressao(){// codigo 1
        
        if(toks.getTipo() == TokenAll.ABREPARENTESES){
            proximoToken();
            if(this.expressaoParentese()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão parentese codigo 1");
                return false;
            }
        }
        if(this.termo()){
            System.out.println("entrou em termo codigo 1");
            if(this.proxTrecSoma()){
                if(this.proxTrechoRelacional()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho relacional codigo 1");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho soma codigo 1");
                return false;
            }
        }
        if((toks.getTipo() == TokenAll.verdadeiro)||(toks.getTipo() == TokenAll.falso)){
            System.out.println("booleanos código1");
            proximoToken();
            if(this.proxTrecExpLog()){
                return true;
            }
        }
        return false;
    }

    public boolean expressaoParentese(){//codigo 2
        System.out.println("entrou em expressão parentese");
        if(toks.getTipo() == TokenAll.ABREPARENTESES){
            proximoToken();
            if(this.complementoExpressãoParentese()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado complemento expressão parentese codigo 2");
                return false;
            }
        }
        if((toks.getTipo() == TokenAll.verdadeiro)||(toks.getTipo() == TokenAll.falso)){
            proximoToken();
            if(this.proxTrecExpLog()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho de expressão lógica codigo 2");
                return false;
            }
        }
        if(termo()){
            System.out.println("termo código 2");
            if(this.proxTrecSoma()){
                if(this.proxTrechoGeral()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho global codigo 2");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho soma codigo 2");
                return false;
            }
        }
        return false;
    }

    public boolean complementoExpressãoParentese(){ //codigo 3
        
        if(this.termo1Parenteses()){
            if(this.proxTrecExpLog()){
                if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                    proximoToken();
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" complementoExpressãoParentese codigo 3");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho de expressão lógica. codigo 3");
                return false;
            }
        }
        return false;
    }

    public boolean proxTrechoGeral(){//codigo 4
    
        System.out.println("entrou em proxTrechoGeral");
        if((toks.getTipo() == TokenAll.MAIOR) || (toks.getTipo() == TokenAll.MAIOR_IGUAL)
                || (toks.getTipo() == TokenAll.MENOR) || (toks.getTipo() == TokenAll.MENOR_IGUAL)
                || (toks.getTipo() == TokenAll.IGUALDADE) || (toks.getTipo() == TokenAll.DIFERENCA)){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(this.proxTrecExpLog()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" proxTrechoGeral codigo 4");
                        return false;
                    }
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressao aritmética codigo 4");
                return false;
            }
        }

        if(toks.getTipo() == TokenAll.FECHAPARENTESES){
            proximoToken();
            if(this.complementoExpAritParentese()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado complemento de expressão aritmética codigo 4");
                return false;
            }
        }
        return false;
    }

    public boolean complementoExpAritParentese(){ //codigo 5
        
        if((toks.getTipo() == TokenAll.MAIOR) || (toks.getTipo() == TokenAll.MAIOR_IGUAL)
                || (toks.getTipo() == TokenAll.MENOR) || (toks.getTipo() == TokenAll.MENOR_IGUAL)
                || (toks.getTipo() == TokenAll.IGUALDADE) || (toks.getTipo() == TokenAll.DIFERENCA)){
            this.operadorRelacional();
            System.out.println("achou relacional: complementoExpAritParentese " + ponteiro);
            if(this.expressaoAritmetica()){
                System.out.println("achou expAritmética: complementoExpAritParentese " + ponteiro);
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética codigo 5");
                return false;
            }
        }
        return true;
    }

    public boolean proxTrechoRelacional(){//código 6
        
        if((toks.getTipo() == TokenAll.MAIOR) || (toks.getTipo() == TokenAll.MAIOR_IGUAL)
                || (toks.getTipo() == TokenAll.MENOR) || (toks.getTipo() == TokenAll.MENOR_IGUAL)
                || (toks.getTipo() == TokenAll.IGUALDADE) || (toks.getTipo() == TokenAll.DIFERENCA)){
            this.operadorRelacional();
            if(this.expressaoAritmetica()){
                if(this.proxTrecExpLog()){
                    return true;
                }else{
                    System.out.println("Deu pau no caralho do proximo trecho exp lógica!!! codigo 6" + ponteiro);
                    return false;
                }
            }else{
                System.out.println("Deu pau no caralho da expressão aritmética!!! " + ponteiro);
                return false;
            }
        }
        return true;
    }

    public boolean expressaoAritmetica(){//código 7
 
        System.out.println("entrou em expressão aritmética");
        System.out.println("ponteiro: " + ponteiro);
        if(toks.getTipo() != TokenAll.ABREPARENTESES){
            this.termo();
            System.out.println("ponteiro-a: " + ponteiro);
            if(this.proxTrecSoma()){
                System.out.println("ponteiro-b: " + ponteiro);
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho soma codigo 7");
                return false;
            }
        }

        if(toks.getTipo() == TokenAll.ABREPARENTESES){
            System.out.println("ponteiro-c: " + ponteiro);
            proximoToken();
            if(this.expressaoAritmetica()){
                System.out.println("ponteiro-d: " + ponteiro);
          //      proximoToken();
                if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                    System.out.println("ponteiro-fecha parenteses: " + ponteiro);
                    proximoToken();
                    System.out.println("ponteiro-fecha parenteses depois: " + ponteiro);
                }else{
                     erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" codigo 7");
                     return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmetica! ");
                return false;
            }
        }
        return false;
    }

    public boolean fator(){//código 8
        System.out.println("Entrou em fator!!");
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.complementoFatorVariavel()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Complemento inconsistente! codigo 8");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.NUMERO){
            System.out.println("numero = " + ponteiro);
            proximoToken();
            System.out.println("depois numero = " + ponteiro);
            return true;
        }
        return false;
    }

    public boolean complementoFatorVariavel(){//código 9

        System.out.println("entrou em complemento variavel...");

        if(toks.getTipo() == TokenAll.ABRECHOCHETES){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(toks.getTipo() == TokenAll.FECHACOCHETES){
                    proximoToken();
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"]\" codigo 9");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmetica! codigo 9");
                return false;
            }

        }
        if(toks.getTipo() == TokenAll.PONTO){
                this.loopAcessoAtribObjeto();
                return true;
        }
        return true;
    }

    public boolean proxTrecMultiplicacao(){//codigo 10

        System.out.println("entrou em proximo trecho multiplicação");

        if((toks.getTipo() == TokenAll.MULTIPLICACAO) || (toks.getTipo() == TokenAll.DIVISAO)){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(this.proxTrecMultiplicacao()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho multiplicação codigo 10");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmetica! codigo 10");
                return false;
            }
        }
        return true;
    }

    public boolean proxTrecSoma(){// codigo 11
        boolean retorno = true;
        System.out.println("entrou em proximo trecho soma");
        if((toks.getTipo() == TokenAll.SOMA) || (toks.getTipo() == TokenAll.SUBTRACAO)){
            System.out.println("antes da soma: " + ponteiro);
            proximoToken();
            System.out.println("depois da soma: " + ponteiro);
            if(this.expressaoAritmetica()){
                System.out.println("antes exp arit soma: " + ponteiro);
               // proximoToken();
                System.out.println("depois exp arit soma: " + ponteiro);
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmetica. codigo 11");
                retorno = false;
            }
        }
        return retorno;
    }

    public boolean expressaoLogica(){//codigo 12
        boolean retorno = true;
        System.out.println("Entrou em expressão lógica!!");
        if(this.termo1()){
            System.out.println("ponteiro exp log: " + ponteiro);
            //proximoToken();
            if(this.proxTrecExpLog()){
                System.out.println("expressão lógica - ptel: " + ponteiro);
                //proximoToken();
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão lógica codigo 12");
                retorno = false;
            }
        }else{
            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado termo 1 codigo 12");
            retorno = false;
        }
        return retorno;
    }
    
    public boolean termo(){//codigo 13
        System.out.println("entrou em termo!");
        System.out.println("ponteiro-termo-a: " + ponteiro);
        if(this.fator()){
            System.out.println("ponteiro-termo-b: " + ponteiro);
            if(this.proxTrecMultiplicacao()){
                System.out.println("ponteiro-termo-c: " + ponteiro);
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho multiplicaçao codigo 13");
                return false;
            }
        }
        return false;
    }

    public boolean termo1(){//codigo 14
       System.out.println("entrou em termo 1");
       if(this.expressaoBooleana()){
           return true;
       }
       if(toks.getTipo() == TokenAll.ABREPARENTESES){
           proximoToken();
           if(this.termo1Parenteses()){
               return true;
           }else{
               erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado termo 1 parenteses. codigo 14");
               return false;
           }
       }
       if(this.termo()){
           if(this.proxTrecSoma()){
               if(this.operadorRelacional()){
                   if(this.expressaoAritmetica()){
                       return true;
                   }else{
                       erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética codigo 14");
                       return false;
                   }
               }else{
                   erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado operador relacional codigo 14");
                   return false;
               }
           }else{
               erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado proximo trecho soma. codigo 14");
               return false;
           }
       }
       return false;
    }


    public boolean termo1Parenteses(){//codigo 15
        System.out.println("entrou em termo 1 parenteses");
        if(this.expressaoAritmetica()){
            if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                proximoToken();
                if(this.operadorRelacional()){
                    if(this.expressaoAritmetica()){
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética. codigo 15");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado operador relacional codigo 15");
                    return false;
                }
            }
        }
        if(this.proxTrecExpLog()){
            //proximoToken();
            if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                proximoToken();
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" codigo 15");
                return false;
            }
        }
        return false;
    }

    public boolean complementoTermo1Parenteses(){//código 16
        if(toks.getTipo() == TokenAll.FECHAPARENTESES){
            proximoToken();
            if(this.operadorRelacional()){
                if(this.expressaoAritmetica()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética! codigo 16");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado operador relacional! codigo 16");
                return false;
            }
        }
        if(this.proxTrecExpLog()){
            if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                proximoToken();
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" codigo 16");
                return false;
            }
        }
        if(this.proxTrechoRelacional()){
            if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                proximoToken();
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" codigo 16");
                return false;
            }
        }
        return false;
    }

    //consertar problemas com os parenteses, provavelmente chama um método na hora errada.
    public boolean proxTrecExpLog(){//código 17
        System.out.println("entrou em proxTrecExpLog");

        if((toks.getTipo() == TokenAll.E) || (toks.getTipo() == TokenAll.OU)){
            System.out.println("teste em ptrecExpLog: " + ponteiro);
            proximoToken();
            System.out.println("ptel antes explog: " + ponteiro);
            if(this.expressaoLogica()){
                System.out.println("ptel depois de explog: " + ponteiro);
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado operador lógico! codigo 17");
                return false;
            }
        }
        return false;
    }

    public boolean operadorLogico(){//codigo 18
        boolean retorno = true;
        System.out.println("Entrou em operador lógico");

        if((toks.getTipo() == TokenAll.E) || (toks.getTipo() == TokenAll.OU)){
            System.out.println("antes do incremento: " + ponteiro);
            proximoToken();
            System.out.println("testou o operador lógico: " + ponteiro);
        }else{
            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado operador lógico! codigo 18");
            retorno = false;
        }
        return retorno;
    }

    public boolean operadorRelacional(){//codigo 19
        boolean retorno = true;
        System.out.println("entrou em operador relacional");

        if((toks.getTipo() == TokenAll.MAIOR) || (toks.getTipo() == TokenAll.MAIOR_IGUAL)
                || (toks.getTipo() == TokenAll.MENOR) || (toks.getTipo() == TokenAll.MENOR_IGUAL)
                || (toks.getTipo() == TokenAll.IGUALDADE) || (toks.getTipo() == TokenAll.DIFERENCA)){
            proximoToken();
            System.out.println("operador relacional - achou!!");
        }else{
            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado operador relacional! codigo 19");
            retorno = false;
        }
        return retorno;
    }

    public boolean expressaoBooleana(){//codigo 20
        boolean retorno = true;
        System.out.println("entrou em expressão booleana");

        if((toks.getTipo() == TokenAll.verdadeiro)||(toks.getTipo() == TokenAll.falso)){
            proximoToken();
        }else{
            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão booleana! codigo 20");
            retorno = false;
        }
        return retorno;
    }

    //###########################################################################################################

    //###########################################################################################################
    //                                           COMANDOS
    //###########################################################################################################

    public boolean comando(){
        if(this.comandoGeral()){
            if(this.comando()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado comando ");
                return false;
            }
        }
        return true;
    }

    public boolean comandoGeral(){
        if(this.comandoLinha()){
            if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                proximoToken();
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                return false;
            }
        }
        if(this.comandoBloco()){
            return true;
        }
        return false;
    }

    public boolean comandoLinha(){
        if(this.comandoEscreva()){
            return true;
        }
        if(this.comandoLeia()){
            return true;
        }
        if(retorno()){
            return true;
        }
        if(this.incrementoDecremento()){
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                return false;
            }
        }
        if(toks.getTipo()==TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.complementoVariavelComando()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado complemento de variável ");
                return false;
            }
        }
        return false;
    }

    public boolean comandoBloco(){
        if(this.comandoSe()){
            return true;
        }
        if(this.comandoPara()){
            return true;
        }
        if(this.comandoEnquanto()){
            return true;
        }
        return false;
    }

    public boolean complementoVariavelComando(){
        if(toks.getTipo() == TokenAll.ABRECHOCHETES){
            proximoToken();
            if(this.expressaoAritmetica()){
                if(toks.getTipo() == TokenAll.FECHACOCHETES){
                    proximoToken();
                    if(toks.getTipo() == TokenAll.ATRIBUICAO){
                        proximoToken();
                        if(this.segundoMembroAtribuicao()){
                            return true;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"=\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"]\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão aritmética. ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.ATRIBUICAO){
            proximoToken();
            if(this.segundoMembroAtribuicao()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado segundo membro da atribuição ");
                return false;
            }
        }
        if(this.incrementoDecremento()){
            return true;
        }
        return false;
    }

    public boolean complementoPontoComando(){
        boolean retorno = true;
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.loopAcessoAtribObjeto()){
                //proximoToken();
            }else{
                retorno = false;
            }
        }else{
            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
            retorno = false;
        }
        return retorno;
    }

    public boolean loopAcessoAtribObjeto(){
        boolean retorno = true;
        System.out.println("entrou no loop atrib objeto!");
        
        while((toks.getTipo() == TokenAll.PONTO) || (toks.getTipo() == TokenAll.IDENTIFICADOR)){
            if((toks.getTipo() == TokenAll.PONTO)){
                proximoToken();
                if((toks.getTipo() == TokenAll.IDENTIFICADOR)){
                    proximoToken();
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                    retorno = false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \".\" ");
                retorno = false;
            }
        }
        return retorno;
    }

    public boolean comandoSe(){
        if(toks.getTipo() == TokenAll.se){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.expressaoLogica()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        if(toks.getTipo() == TokenAll.entao){
                            proximoToken();
                            if(toks.getTipo() == TokenAll.ABRECHAVES){
                                proximoToken();
                                if(this.comando()){
                                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                                        proximoToken();
                                        if(this.complementoComandoSe()){
                                            return true;
                                        }
                                    }else{
                                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                                        return false;
                                    }
                                }
                            }else{
                                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                                return false;
                            }
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado entao ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão lógica ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }

    public boolean complementoComandoSe(){
        if(toks.getTipo() == TokenAll.senao){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABRECHAVES){
                proximoToken();
                if(this.comando()){
                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                        return false;
                    }
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                return false;
            }
        }
        return true;
    }

    public boolean comandoPara(){
        if(toks.getTipo() == TokenAll.para){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.atribuicao()){
                    if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                        proximoToken();
                        if(this.expressaoLogica()){
                            if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                                proximoToken();
                                if(this.atribuicao()){
                                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                                        proximoToken();
                                        if(toks.getTipo()== TokenAll.ABRECHAVES){
                                            proximoToken();
                                            if(this.comando()){
                                                if(toks.getTipo() == TokenAll.FECHACHAVES){
                                                    proximoToken();
                                                    return true;
                                                }else{
                                                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                                                    return false;
                                                }
                                            }
                                        }else{
                                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                                            return false;
                                        }
                                    }else{
                                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                                        return false;
                                    }
                                }else{
                                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado atribuição ");
                                    return false;
                                }
                            }else{
                                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                                return false;
                            }
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão lógica ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado atribuição ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }

    public boolean comandoEnquanto(){
        if(toks.getTipo() == TokenAll.enquanto){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.expressaoLogica()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        if(toks.getTipo() == TokenAll.ABRECHAVES){
                            proximoToken();
                            if(this.comando()){
                                if(toks.getTipo() == TokenAll.FECHACHAVES){
                                    proximoToken();
                                    return true;
                                }else{
                                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                                    return false;
                                }
                            }
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão lógica ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }

    public boolean comandoEscreva(){
        if(toks.getTipo() == TokenAll.escreva){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.paramEscreva()){
                    if(toks.getTipo() ==TokenAll.FECHAPARENTESES){
                        proximoToken();
                        return true;
                    }else{
                         erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                         return false;
                    }
                }else{
                     erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado parametro escreva ");
                     return false;
                }
            }else{
                 erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                 return false;
            }
        }
        return false;
    }

    public boolean paramEscreva(){
        if(toks.getTipo() == TokenAll.CADEIA_CONSTANTE){
            proximoToken();
            if(toks.getTipo() == TokenAll.VIRGULA){
                proximoToken();
                if(this.paramEscreva()){
                    return true;
                }
            }else{
                return true;
            }
        }
        if(this.expressao()){
            if(toks.getTipo() == TokenAll.VIRGULA){
                proximoToken();
                if(this.paramEscreva()){
                    return true;
                }
            }else{
                return true;
            }
        }
        return false;
    }

    public boolean comandoLeia(){
        if(toks.getTipo() == TokenAll.leia){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.paramsLeia()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado parametros de leia. ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }
    
    public boolean paramsLeia(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.loopParamsLeia()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Erros no parâmetro leia! ");
                return false;
            }
        }
        return false;
    }

    public boolean loopParamsLeia(){
       
        while((toks.getTipo() == TokenAll.VIRGULA) || (toks.getTipo()==TokenAll.IDENTIFICADOR)){
            if(toks.getTipo() == TokenAll.VIRGULA){
                proximoToken();
                if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                    proximoToken();
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                    return false;
                }
            }
        }
        return true;
    }

    public boolean comandoIncremento(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.incrementoDecremento()){
                return true;
            }
        }
        if(this.incrementoDecremento()){
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                proximoToken();
                return true;
            }
        }
        return false;
    }

    public boolean incrementoDecremento(){
        if((toks.getTipo() == TokenAll.INCREMENTO) || (toks.getTipo() == TokenAll.DECREMENTO)){
            proximoToken();
            return true;
        }
        return false;
    }

    public boolean retorno(){
        if(toks.getTipo() == TokenAll.retorno){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.expressao()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado expressão ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }


    //###########################################################################################################

    //###########################################################################################################
    //                                           CHAMADA DE MÉTODOS
    //###########################################################################################################

    public boolean chamadaMetodo(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.complementoChamadaMetodo()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado complemento de método ");
                return false;
            }
        }
        return false;
    }

    public boolean complementoChamadaMetodo(){
        if(toks.getTipo() == TokenAll.ABREPARENTESES){
            proximoToken();
            if(this.parametrosReais()){
                if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                    proximoToken();
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado parametros reais ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.PONTO){
            proximoToken();
            if(this.chamadaMetodo()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado chamada de método ");
                return false;
            }
        }
        return false;
    }

    public boolean parametrosReais(){
        if(this.parametroReal()){
            if(toks.getTipo() == TokenAll.VIRGULA){
                proximoToken();
                if(this.parametrosReais()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado parâmetros reais ");
                    return false;
                }
            }
        }else{
            return true;
        }
        return true;
    }

    public boolean parametroReal(){
        if((toks.getTipo() == TokenAll.IDENTIFICADOR) || (toks.getTipo() == TokenAll.NUMERO)
                ||(toks.getTipo() == TokenAll.CADEIA_CONSTANTE) || (toks.getTipo() == TokenAll.CHAR)
                || (toks.getTipo() == TokenAll.verdadeiro) || (toks.getTipo() == TokenAll.falso)){
            proximoToken();
            return true;
        }
        return false;
    }

    //###########################################################################################################

    //###########################################################################################################
    //                                           OBJETOS
    //###########################################################################################################

    public boolean instanciarObjetos(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(toks.getTipo() == TokenAll.IDENTIFICADOR){
                proximoToken();
                if(this.complementoVariavelInstObjeto()){
                    return true;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado identificador ");
                return false;
            }
        }
        return true;
    }

    public boolean complementoVariavelInstObjeto(){
        if(toks.getTipo() == TokenAll.ABREPARENTESES){
            proximoToken();
            if(this.parametrosReaisInstanciaObjetos()){
                if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado parâmetros ");
                return false;
            }
        }
        return true;
    }

    public boolean parametrosReaisInstanciaObjetos(){
        if(this.parametroReal()){
            if(this.loopParametrosReaisInstanciaObjetos()){
                return true;
            }
        }
        return false;
    }

    public boolean loopParametrosReaisInstanciaObjetos(){

        if(toks.getTipo() == TokenAll.VIRGULA){
            proximoToken();
            if(this.parametrosReaisInstanciaObjetos()){
                return true;
            }
        }
        return true;
    }

    //###########################################################################################################

    //###########################################################################################################
    //                                           MÉTODOS
    //###########################################################################################################

    public boolean blocoMetodos(){
        if(toks.getTipo() == TokenAll.metodos){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABRECHAVES){
                proximoToken();
                if(this.declaraMetodos()){
                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                        proximoToken();
                        return true;
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado declaração de métodos no bloco ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                return false;
            }
        }
        return true;
    }

    public boolean declaraMetodos(){
        if((toks.getTipo() == TokenAll.inteiro) || (toks.getTipo() == TokenAll.real)
                || (toks.getTipo() == TokenAll.logico) || (toks.getTipo() == TokenAll.cadeia)
                || (toks.getTipo() == TokenAll.caractere)){
            proximoToken();
            if(this.declaracaoMetodo()){
                if(this.declaraMetodos()){
                    return true;
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado declara metodos ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado declaração de métodos ");
                return false;
            }
        }
        if(toks.getTipo() == TokenAll.vazio){
            if(this.declaracaoMetodoVazio()){
                return true;
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado declaração método vazio. ");
                return false;
            }
        }
        return true;
    }

    public boolean declaracaoMetodoVazio(){
        if(this.declaracaoMetodo()){
            if(this.declaraMetodos()){
                return true;
            }
        }
        if(toks.getTipo() == TokenAll.principal){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(toks.getTipo() == TokenAll.vazio){
                    proximoToken();
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        if(toks.getTipo() == TokenAll.ABRECHAVES){
                            proximoToken();
                            if(this.blocoVariaveis()){
                                if(this.comando()){
                                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                                        proximoToken();
                                        return true;
                                    }else{
                                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                                        return false;
                                    }
                                }
                            }
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado palavra reservada vazio ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }

    public boolean declaracaoMetodo(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(toks.getTipo() == TokenAll.ABREPARENTESES){
                proximoToken();
                if(this.parametrosFormais()){
                    if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                        proximoToken();
                        if(toks.getTipo() == TokenAll.ABRECHAVES){
                            if(this.decVarMetodo()){
                                if(this.comando()){
                                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                                        proximoToken();
                                        return true;
                                    }else{
                                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                                        return false;
                                    }
                                }
                            }
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado parametros formais ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                return false;
            }
        }
        return false;
    }

    public boolean decVarMetodo(){
        if(this.blocoVariaveis()){
            return true;
        }
        return true;
    }

    public boolean parametrosFormais(){
        if(this.parametrosMesmoTipo()){
            if(this.parametrosFormais()){
                return true;
            }
        }
        return true;
    }

    public boolean parametrosMesmoTipo(){
        if(this.tipoVariavel()){
            if(this.listaParametros()){
                if(toks.getTipo() == TokenAll.PONTOEVIRGULA){
                    proximoToken();
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \";\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado lista de parametros ");
                return false;
            }
        }
        return false;
    }

    public boolean listaParametros(){
        if(toks.getTipo() == TokenAll.IDENTIFICADOR){
            proximoToken();
            if(this.loopListaParametros()){
                return true;
            }
        }
        return false;
    }

    public boolean loopListaParametros(){
        if(toks.getTipo() == TokenAll.VIRGULA){
            proximoToken();
            if(this.listaParametros()){
                return true;
            }
        }
        return true;
    }

    public boolean metodoPrincipal(){
        if(toks.getTipo() == TokenAll.vazio){
            proximoToken();
            if(toks.getTipo() == TokenAll.principal){
                proximoToken();
                if(toks.getTipo() == TokenAll.ABREPARENTESES){
                    proximoToken();
                    if(toks.getTipo() == TokenAll.vazio){
                        proximoToken();
                        if(toks.getTipo() == TokenAll.FECHAPARENTESES){
                            proximoToken();
                            if(toks.getTipo() == TokenAll.ABRECHAVES){
                                proximoToken();
                                //declaração de variaveis
                                if(this.comando()){
                                    if(toks.getTipo() == TokenAll.FECHACHAVES){
                                        proximoToken();
                                        return true;
                                    }else{
                                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"}\" ");
                                        return false;
                                    }
                                }
                            }else{
                                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"{\" ");
                                return false;
                            }
                        }else{
                            erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \")\" ");
                            return false;
                        }
                    }else{
                        erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado palavra reservada vazio ");
                        return false;
                    }
                }else{
                    erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado \"(\" ");
                    return false;
                }
            }else{
                erros.add("ERRO SINTATICO - Linha: " + toks.getLinha() + " Esperado palavra reservada principal ");
                return false;
            }
        }
        return false;
    }

    //###########################################################################################################




}//fim da classe Sintatico
